new enum GtkSortType.
authorStefan Jeske <stefan@gtk.org>
Wed, 5 Aug 1998 20:02:32 +0000 (20:02 +0000)
committerStefan Jeske <stefan@src.gnome.org>
Wed, 5 Aug 1998 20:02:32 +0000 (20:02 +0000)
Wed Aug  5 21:12:37 1998  Stefan Jeske  <stefan@gtk.org>

* gtk/gtkenums.h: new enum GtkSortType.

* gtk/gtkclist.h:
* gtk/gtkclist.c:
Added sorting capabilities to GtkCList. New APIs :
gtk_clist_set_compare_func, gtk_clist_set_sort_column,
gtk_clist_set_sort_type, gtk_clist_sort, gtk_clist_set_auto_sort.
New internal functions : default_compare, merge, mergesort.

(gtk_clist_append): This is just a wrapper for gtk_clist_insert now.

(gtk_clist_insert): Modified to handle gtk_clist_append and the
auto sort flag. Changed the return value from void to gint to
return the row number where the element was actually inserted.

(gtk_clist_swap_rows): Return immediately if auto sort flag is set.

* gtk/gtkctree.h:
* gtk/gtkctree.c:
Removed the auto_sort flag, replaced ctree->node_compare with
clist->compare all over the place, modified default_compare to
match clist's needs. Removed API´s : gtk_ctree_set_auto_sort,
gtk_ctree_set_compare_func. Removed GtkCTreeCompareFunc typedef.

* gtk/testgtk.c: Modified clist/ctree samples to demonstrate
sorting. The lists can be sorted by a column by clicking the
corresponding title button.

14 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gtk/gtkclist.c
gtk/gtkclist.h
gtk/gtkctree.c
gtk/gtkctree.h
gtk/gtkenums.h
gtk/testgtk.c
tests/testgtk.c

index b47db2be73caa8d7cfb800c4a0f52da42139bff4..2fd2cdc64a355196e32d653f80b788a68987c089 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,33 @@
+Wed Aug  5 21:12:37 1998  Stefan Jeske  <stefan@gtk.org>
+
+       * gtk/gtkenums.h: new enum GtkSortType.
+       
+       * gtk/gtkclist.h:
+       * gtk/gtkclist.c:
+       Added sorting capabilities to GtkCList. New APIs :
+       gtk_clist_set_compare_func, gtk_clist_set_sort_column,
+       gtk_clist_set_sort_type, gtk_clist_sort, gtk_clist_set_auto_sort. 
+       New internal functions : default_compare, merge, mergesort.
+
+       (gtk_clist_append): This is just a wrapper for gtk_clist_insert now.
+       
+       (gtk_clist_insert): Modified to handle gtk_clist_append and the
+       auto sort flag. Changed the return value from void to gint to
+       return the row number where the element was actually inserted.
+
+       (gtk_clist_swap_rows): Return immediately if auto sort flag is set.
+       
+       * gtk/gtkctree.h:
+       * gtk/gtkctree.c:
+       Removed the auto_sort flag, replaced ctree->node_compare with
+       clist->compare all over the place, modified default_compare to
+       match clist's needs. Removed API´s : gtk_ctree_set_auto_sort,
+       gtk_ctree_set_compare_func. Removed GtkCTreeCompareFunc typedef.
+
+       * gtk/testgtk.c: Modified clist/ctree samples to demonstrate
+       sorting. The lists can be sorted by a column by clicking the 
+       corresponding title button.
+       
 Tue Aug  4 22:02:49 PDT 1998 Shawn T. Amundson <amundson@gtk.org>
 
        * Released GTK+ 1.1.1
index b47db2be73caa8d7cfb800c4a0f52da42139bff4..2fd2cdc64a355196e32d653f80b788a68987c089 100644 (file)
@@ -1,3 +1,33 @@
+Wed Aug  5 21:12:37 1998  Stefan Jeske  <stefan@gtk.org>
+
+       * gtk/gtkenums.h: new enum GtkSortType.
+       
+       * gtk/gtkclist.h:
+       * gtk/gtkclist.c:
+       Added sorting capabilities to GtkCList. New APIs :
+       gtk_clist_set_compare_func, gtk_clist_set_sort_column,
+       gtk_clist_set_sort_type, gtk_clist_sort, gtk_clist_set_auto_sort. 
+       New internal functions : default_compare, merge, mergesort.
+
+       (gtk_clist_append): This is just a wrapper for gtk_clist_insert now.
+       
+       (gtk_clist_insert): Modified to handle gtk_clist_append and the
+       auto sort flag. Changed the return value from void to gint to
+       return the row number where the element was actually inserted.
+
+       (gtk_clist_swap_rows): Return immediately if auto sort flag is set.
+       
+       * gtk/gtkctree.h:
+       * gtk/gtkctree.c:
+       Removed the auto_sort flag, replaced ctree->node_compare with
+       clist->compare all over the place, modified default_compare to
+       match clist's needs. Removed API´s : gtk_ctree_set_auto_sort,
+       gtk_ctree_set_compare_func. Removed GtkCTreeCompareFunc typedef.
+
+       * gtk/testgtk.c: Modified clist/ctree samples to demonstrate
+       sorting. The lists can be sorted by a column by clicking the 
+       corresponding title button.
+       
 Tue Aug  4 22:02:49 PDT 1998 Shawn T. Amundson <amundson@gtk.org>
 
        * Released GTK+ 1.1.1
index b47db2be73caa8d7cfb800c4a0f52da42139bff4..2fd2cdc64a355196e32d653f80b788a68987c089 100644 (file)
@@ -1,3 +1,33 @@
+Wed Aug  5 21:12:37 1998  Stefan Jeske  <stefan@gtk.org>
+
+       * gtk/gtkenums.h: new enum GtkSortType.
+       
+       * gtk/gtkclist.h:
+       * gtk/gtkclist.c:
+       Added sorting capabilities to GtkCList. New APIs :
+       gtk_clist_set_compare_func, gtk_clist_set_sort_column,
+       gtk_clist_set_sort_type, gtk_clist_sort, gtk_clist_set_auto_sort. 
+       New internal functions : default_compare, merge, mergesort.
+
+       (gtk_clist_append): This is just a wrapper for gtk_clist_insert now.
+       
+       (gtk_clist_insert): Modified to handle gtk_clist_append and the
+       auto sort flag. Changed the return value from void to gint to
+       return the row number where the element was actually inserted.
+
+       (gtk_clist_swap_rows): Return immediately if auto sort flag is set.
+       
+       * gtk/gtkctree.h:
+       * gtk/gtkctree.c:
+       Removed the auto_sort flag, replaced ctree->node_compare with
+       clist->compare all over the place, modified default_compare to
+       match clist's needs. Removed API´s : gtk_ctree_set_auto_sort,
+       gtk_ctree_set_compare_func. Removed GtkCTreeCompareFunc typedef.
+
+       * gtk/testgtk.c: Modified clist/ctree samples to demonstrate
+       sorting. The lists can be sorted by a column by clicking the 
+       corresponding title button.
+       
 Tue Aug  4 22:02:49 PDT 1998 Shawn T. Amundson <amundson@gtk.org>
 
        * Released GTK+ 1.1.1
index b47db2be73caa8d7cfb800c4a0f52da42139bff4..2fd2cdc64a355196e32d653f80b788a68987c089 100644 (file)
@@ -1,3 +1,33 @@
+Wed Aug  5 21:12:37 1998  Stefan Jeske  <stefan@gtk.org>
+
+       * gtk/gtkenums.h: new enum GtkSortType.
+       
+       * gtk/gtkclist.h:
+       * gtk/gtkclist.c:
+       Added sorting capabilities to GtkCList. New APIs :
+       gtk_clist_set_compare_func, gtk_clist_set_sort_column,
+       gtk_clist_set_sort_type, gtk_clist_sort, gtk_clist_set_auto_sort. 
+       New internal functions : default_compare, merge, mergesort.
+
+       (gtk_clist_append): This is just a wrapper for gtk_clist_insert now.
+       
+       (gtk_clist_insert): Modified to handle gtk_clist_append and the
+       auto sort flag. Changed the return value from void to gint to
+       return the row number where the element was actually inserted.
+
+       (gtk_clist_swap_rows): Return immediately if auto sort flag is set.
+       
+       * gtk/gtkctree.h:
+       * gtk/gtkctree.c:
+       Removed the auto_sort flag, replaced ctree->node_compare with
+       clist->compare all over the place, modified default_compare to
+       match clist's needs. Removed API´s : gtk_ctree_set_auto_sort,
+       gtk_ctree_set_compare_func. Removed GtkCTreeCompareFunc typedef.
+
+       * gtk/testgtk.c: Modified clist/ctree samples to demonstrate
+       sorting. The lists can be sorted by a column by clicking the 
+       corresponding title button.
+       
 Tue Aug  4 22:02:49 PDT 1998 Shawn T. Amundson <amundson@gtk.org>
 
        * Released GTK+ 1.1.1
index b47db2be73caa8d7cfb800c4a0f52da42139bff4..2fd2cdc64a355196e32d653f80b788a68987c089 100644 (file)
@@ -1,3 +1,33 @@
+Wed Aug  5 21:12:37 1998  Stefan Jeske  <stefan@gtk.org>
+
+       * gtk/gtkenums.h: new enum GtkSortType.
+       
+       * gtk/gtkclist.h:
+       * gtk/gtkclist.c:
+       Added sorting capabilities to GtkCList. New APIs :
+       gtk_clist_set_compare_func, gtk_clist_set_sort_column,
+       gtk_clist_set_sort_type, gtk_clist_sort, gtk_clist_set_auto_sort. 
+       New internal functions : default_compare, merge, mergesort.
+
+       (gtk_clist_append): This is just a wrapper for gtk_clist_insert now.
+       
+       (gtk_clist_insert): Modified to handle gtk_clist_append and the
+       auto sort flag. Changed the return value from void to gint to
+       return the row number where the element was actually inserted.
+
+       (gtk_clist_swap_rows): Return immediately if auto sort flag is set.
+       
+       * gtk/gtkctree.h:
+       * gtk/gtkctree.c:
+       Removed the auto_sort flag, replaced ctree->node_compare with
+       clist->compare all over the place, modified default_compare to
+       match clist's needs. Removed API´s : gtk_ctree_set_auto_sort,
+       gtk_ctree_set_compare_func. Removed GtkCTreeCompareFunc typedef.
+
+       * gtk/testgtk.c: Modified clist/ctree samples to demonstrate
+       sorting. The lists can be sorted by a column by clicking the 
+       corresponding title button.
+       
 Tue Aug  4 22:02:49 PDT 1998 Shawn T. Amundson <amundson@gtk.org>
 
        * Released GTK+ 1.1.1
index b47db2be73caa8d7cfb800c4a0f52da42139bff4..2fd2cdc64a355196e32d653f80b788a68987c089 100644 (file)
@@ -1,3 +1,33 @@
+Wed Aug  5 21:12:37 1998  Stefan Jeske  <stefan@gtk.org>
+
+       * gtk/gtkenums.h: new enum GtkSortType.
+       
+       * gtk/gtkclist.h:
+       * gtk/gtkclist.c:
+       Added sorting capabilities to GtkCList. New APIs :
+       gtk_clist_set_compare_func, gtk_clist_set_sort_column,
+       gtk_clist_set_sort_type, gtk_clist_sort, gtk_clist_set_auto_sort. 
+       New internal functions : default_compare, merge, mergesort.
+
+       (gtk_clist_append): This is just a wrapper for gtk_clist_insert now.
+       
+       (gtk_clist_insert): Modified to handle gtk_clist_append and the
+       auto sort flag. Changed the return value from void to gint to
+       return the row number where the element was actually inserted.
+
+       (gtk_clist_swap_rows): Return immediately if auto sort flag is set.
+       
+       * gtk/gtkctree.h:
+       * gtk/gtkctree.c:
+       Removed the auto_sort flag, replaced ctree->node_compare with
+       clist->compare all over the place, modified default_compare to
+       match clist's needs. Removed API´s : gtk_ctree_set_auto_sort,
+       gtk_ctree_set_compare_func. Removed GtkCTreeCompareFunc typedef.
+
+       * gtk/testgtk.c: Modified clist/ctree samples to demonstrate
+       sorting. The lists can be sorted by a column by clicking the 
+       corresponding title button.
+       
 Tue Aug  4 22:02:49 PDT 1998 Shawn T. Amundson <amundson@gtk.org>
 
        * Released GTK+ 1.1.1
index b47db2be73caa8d7cfb800c4a0f52da42139bff4..2fd2cdc64a355196e32d653f80b788a68987c089 100644 (file)
@@ -1,3 +1,33 @@
+Wed Aug  5 21:12:37 1998  Stefan Jeske  <stefan@gtk.org>
+
+       * gtk/gtkenums.h: new enum GtkSortType.
+       
+       * gtk/gtkclist.h:
+       * gtk/gtkclist.c:
+       Added sorting capabilities to GtkCList. New APIs :
+       gtk_clist_set_compare_func, gtk_clist_set_sort_column,
+       gtk_clist_set_sort_type, gtk_clist_sort, gtk_clist_set_auto_sort. 
+       New internal functions : default_compare, merge, mergesort.
+
+       (gtk_clist_append): This is just a wrapper for gtk_clist_insert now.
+       
+       (gtk_clist_insert): Modified to handle gtk_clist_append and the
+       auto sort flag. Changed the return value from void to gint to
+       return the row number where the element was actually inserted.
+
+       (gtk_clist_swap_rows): Return immediately if auto sort flag is set.
+       
+       * gtk/gtkctree.h:
+       * gtk/gtkctree.c:
+       Removed the auto_sort flag, replaced ctree->node_compare with
+       clist->compare all over the place, modified default_compare to
+       match clist's needs. Removed API´s : gtk_ctree_set_auto_sort,
+       gtk_ctree_set_compare_func. Removed GtkCTreeCompareFunc typedef.
+
+       * gtk/testgtk.c: Modified clist/ctree samples to demonstrate
+       sorting. The lists can be sorted by a column by clicking the 
+       corresponding title button.
+       
 Tue Aug  4 22:02:49 PDT 1998 Shawn T. Amundson <amundson@gtk.org>
 
        * Released GTK+ 1.1.1
index ae7d8914402e351b561791b0db493a714662857d..bf05c86d9ff2bbfbefdd537750b03a63e518940e 100644 (file)
@@ -350,6 +350,17 @@ static void extend_selection (GtkCList      *clist,
                              gfloat         position,
                              gboolean       auto_start_selection);
 
+/* Sorting */
+static gint default_compare (GtkCList     *clist,
+                            gconstpointer row1,
+                            gconstpointer row2);
+static GList * merge (GtkCList *clist,
+                     GList    *a,
+                     GList    *b);
+static GList * mergesort (GtkCList *clist,
+                         GList    *list,
+                         gint      num);
+
 /* Fill in data after widget is realized and has style */
 
 static void add_style_data (GtkCList * clist);
@@ -809,6 +820,10 @@ gtk_clist_init (GtkCList * clist)
   clist->drag_pos = -1;
   clist->htimer = 0;
   clist->vtimer = 0;
+
+  clist->compare = default_compare;
+  clist->sort_type = GTK_SORT_ASCENDING;
+  clist->sort_column = 0;
 }
 
 /* Constructors */
@@ -1613,57 +1628,14 @@ gint
 gtk_clist_append (GtkCList * clist,
                  gchar * text[])
 {
-  gint i;
-  GtkCListRow *clist_row;
-
   g_return_val_if_fail (clist != NULL, -1);
   g_return_val_if_fail (GTK_IS_CLIST (clist), -1);
+  g_return_val_if_fail (text != NULL, -1);
 
-  clist_row = row_new (clist);
-  clist->rows++;
-
-  /* set the text in the row's columns */
-  if (text)
-    for (i = 0; i < clist->columns; i++)
-      if (text[i])
-        cell_set_text (clist, clist_row, i, text[i]);
-
-  /* keeps track of the end of the list so the list 
-   * doesn't have to be traversed every time a item is added */
-  if (!clist->row_list)
-    {
-      clist->row_list = g_list_append (clist->row_list, clist_row);
-      clist->row_list_end = clist->row_list;
-
-      /* check the selection mode to see if we should select
-       * the first row automaticly */
-      switch (clist->selection_mode)
-       {
-       case GTK_SELECTION_BROWSE:
-         select_row (clist, 0, -1, NULL);
-         break;
-
-       default:
-         break;
-       }
-    }
-  else
-    clist->row_list_end = (g_list_append (clist->row_list_end, clist_row))->next;
-  
-  /* redraw the list if it's not frozen */
-  if (!GTK_CLIST_FROZEN (clist))
-    {
-      adjust_scrollbars (clist);
-
-      if (gtk_clist_row_is_visible (clist, clist->rows - 1) != GTK_VISIBILITY_NONE)
-       draw_rows (clist, NULL);
-    }
-
-  /* return index of the row */
-  return clist->rows - 1;
+  return gtk_clist_insert (clist, clist->rows, text);
 }
 
-void
+gint
 gtk_clist_insert (GtkCList * clist,
                  gint row,
                  gchar * text[])
@@ -1671,42 +1643,72 @@ gtk_clist_insert (GtkCList * clist,
   gint i;
   GtkCListRow *clist_row;
 
-  g_return_if_fail (clist != NULL);
-  g_return_if_fail (GTK_IS_CLIST (clist));
-  g_return_if_fail (text != NULL);
+  g_return_val_if_fail (clist != NULL, -1);
+  g_return_val_if_fail (GTK_IS_CLIST (clist), -1);
+  g_return_val_if_fail (text != NULL, -1);
 
   /* return if out of bounds */
   if (row < 0 || row > clist->rows)
-    return;
+    return -1;
+
+  /* create the row */
+  clist_row = row_new (clist);
+
+  /* set the text in the row's columns */
+  for (i = 0; i < clist->columns; i++)
+    if (text[i])
+      cell_set_text (clist, clist_row, i, text[i]);
 
-  if (clist->rows == 0)
-    gtk_clist_append (clist, text);
+  if (!clist->rows)
+    {
+      clist->row_list = g_list_append (clist->row_list, clist_row);
+      clist->row_list_end = clist->row_list;
+    }
   else
     {
-      /* create the row */
-      clist_row = row_new (clist);
-
-      /* set the text in the row's columns */
-      if (text)
-       for (i = 0; i < clist->columns; i++)
-         if (text[i])
-           cell_set_text (clist, clist_row, i, text[i]);
+      if (GTK_CLIST_AUTO_SORT (clist))   /* override insertion pos */
+       {
+         GList *work;
+         
+         row = 0;
+         work = clist->row_list;
+         
+         if (clist->sort_type == GTK_SORT_ASCENDING)
+           {
+             while (row < clist->rows &&
+                    clist->compare (clist, clist_row,
+                                    GTK_CLIST_ROW (work)) > 0)
+               {
+                 row++;
+                 work = work->next;
+               }
+           }
+         else
+           {
+             while (row < clist->rows &&
+                    clist->compare (clist, clist_row,
+                                    GTK_CLIST_ROW (work)) < 0)
+               {
+                 row++;
+                 work = work->next;
+               }
+           }
+       }
       
-      /* reset the row end pointer if we're inserting at the
-       * end of the list */
+      /* reset the row end pointer if we're inserting at the end of the list */
       if (row == clist->rows)
        clist->row_list_end = (g_list_append (clist->row_list_end, clist_row))->next;
       else
        clist->row_list = g_list_insert (clist->row_list, clist_row, row);
+    }
+  
+  clist->rows++;
 
-      clist->rows++;
-
-      if (row < ROW_FROM_YPIXEL (clist, 0))
-       clist->voffset -= (clist->row_height + CELL_SPACING);
+  if (row < ROW_FROM_YPIXEL (clist, 0))
+    clist->voffset -= (clist->row_height + CELL_SPACING);
 
-      /* syncronize the selection list */
-      sync_selection (clist, row, SYNC_INSERT);
-    }
+  /* syncronize the selection list */
+  sync_selection (clist, row, SYNC_INSERT);
 
   /* redraw the list if it isn't frozen */
   if (!GTK_CLIST_FROZEN (clist))
@@ -1716,6 +1718,8 @@ gtk_clist_insert (GtkCList * clist,
       if (gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE)
        draw_rows (clist, NULL);
     }
+
+  return row;
 }
 
 void
@@ -1894,6 +1898,9 @@ gtk_clist_swap_rows (GtkCList * clist,
   g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
+  if (GTK_CLIST_AUTO_SORT (clist))
+    return;
+
   if (row1 < 0 || row1 > (clist->rows - 1))
     return;
 
@@ -5989,3 +5996,204 @@ selection_find (GtkCList *clist,
 {
   return g_list_find (clist->selection, GINT_TO_POINTER (row_number));
 }
+
+static gint
+default_compare (GtkCList     *clist,
+                gconstpointer ptr1,
+                gconstpointer ptr2)
+{
+  GtkCListRow *row1 = (GtkCListRow *) ptr1;
+  GtkCListRow *row2 = (GtkCListRow *) ptr2;
+  char *text1;
+  char *text2;
+
+  text1 = GTK_CELL_TEXT (row1->cell[clist->sort_column])->text;
+  text2 = GTK_CELL_TEXT (row2->cell[clist->sort_column])->text;
+
+  return strcmp (text1, text2);
+}
+
+void
+gtk_clist_set_compare_func (GtkCList            *clist,
+                           GtkCListCompareFunc  cmp_func)
+{
+  g_return_if_fail (clist != NULL);
+  g_return_if_fail (GTK_IS_CLIST (clist));
+
+  clist->compare = (cmp_func) ? cmp_func : default_compare;
+}
+
+void       
+gtk_clist_set_auto_sort (GtkCList *clist,
+                        gboolean  auto_sort)
+{
+  g_return_if_fail (clist != NULL);
+  g_return_if_fail (GTK_IS_CLIST (clist));
+  
+  if (GTK_CLIST_AUTO_SORT (clist) && !auto_sort)
+    GTK_CLIST_UNSET_FLAG (clist, CLIST_AUTO_SORT);
+  else if (!GTK_CLIST_AUTO_SORT (clist) && auto_sort)
+    {
+      GTK_CLIST_SET_FLAG (clist, CLIST_AUTO_SORT);
+      gtk_clist_sort (clist);
+    }
+}
+
+void       
+gtk_clist_set_sort_type (GtkCList   *clist,
+                        GtkSortType sort_type)
+{
+  g_return_if_fail (clist != NULL);
+  g_return_if_fail (GTK_IS_CLIST (clist));
+  
+  clist->sort_type = sort_type;
+}
+
+void
+gtk_clist_set_sort_column (GtkCList *clist,
+                          gint      column)
+{
+  g_return_if_fail (clist != NULL);
+  g_return_if_fail (GTK_IS_CLIST (clist));
+
+  if (column < 0 || column >= clist->columns)
+    return;
+
+  clist->sort_column = column;
+}
+
+static GList *
+merge (GtkCList *clist,
+       GList    *a,         /* first list to merge */
+       GList    *b)         /* second list to merge */
+{
+  GList z = { 0 };          /* auxiliary node */
+  GList *c;
+  gint cmp;
+
+  c = &z;
+
+  while (a || b)
+    {
+      if (a && !b)
+       {
+         c->next = a;
+         a->prev = c;
+         c = a;
+         a = a->next;
+         break;
+       }
+      else if (!a && b)
+       {
+         c->next = b;
+         b->prev = c;
+         c = b;
+         b = b->next;
+         break;
+       }
+      else /* a && b */
+       {
+         cmp = clist->compare (clist, GTK_CLIST_ROW (a), GTK_CLIST_ROW (b));
+         if ((cmp >= 0 && clist->sort_type == GTK_SORT_DESCENDING) ||
+             (cmp <= 0 && clist->sort_type == GTK_SORT_ASCENDING) ||
+             (a && !b))
+           {
+             c->next = a;
+             a->prev = c;
+             c = a;
+             a = a->next;
+           }
+         else
+           {
+             c->next = b;
+             b->prev = c;
+             c = b;
+             b = b->next;
+           }
+       }
+    }
+
+  return z.next;
+}
+
+static GList *
+mergesort (GtkCList *clist,
+          GList    *list,         /* the list to sort */
+          gint      num)          /* the list's length */
+{
+  GList *half;
+  gint i;
+
+  if (num == 1)
+    {
+      return list;
+    }
+  else
+    {
+      /* move "half" to the middle */
+      half = list;
+      for (i = 0; i < num / 2; i++)
+       half = half->next;
+
+      /* cut the list in two */
+      half->prev->next = NULL;
+      half->prev = NULL;
+
+      /* recursively sort both lists */
+      return merge (clist,
+                   mergesort (clist, list, num / 2),
+                   mergesort (clist, half, num - num / 2));
+    }
+}
+
+void
+gtk_clist_sort (GtkCList *clist)
+{
+  GList *list;
+  GList *work;
+  gint i;
+  gboolean thaw = FALSE;
+
+  g_return_if_fail (clist != NULL);
+  g_return_if_fail (GTK_IS_CLIST (clist));
+
+  if (clist->rows <= 1)
+    return;
+
+  if (GTK_WIDGET_HAS_GRAB (GTK_WIDGET (clist)))
+    return;
+
+  if (clist->anchor != -1 && clist->selection_mode == GTK_SELECTION_EXTENDED)
+    {
+      GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
+      g_list_free (clist->undo_selection);
+      g_list_free (clist->undo_unselection);
+      clist->undo_selection = NULL;
+      clist->undo_unselection = NULL;
+    }
+   
+  if (!GTK_CLIST_FROZEN (clist))
+    {
+      gtk_clist_freeze (clist);
+      thaw = TRUE;
+    }
+
+  clist->row_list = mergesort (clist, clist->row_list, clist->rows);
+
+  work = clist->selection;
+
+  for (i = 0, list = clist->row_list; i < clist->rows; i++, list = list->next)
+    {
+      if (GTK_CLIST_ROW (list)->state == GTK_STATE_SELECTED)
+       {
+         work->data = GINT_TO_POINTER (i);
+         work = work->next;
+       }
+      
+      if (i == clist->rows - 1)
+       clist->row_list_end = list;
+    }
+
+  if (thaw)
+    gtk_clist_thaw (clist);
+}
index 25f99d559677c73022d22d46589072c3a7e4bd22..2dbe14bcf3b3b8acb6bebb6b815fb7d08e595f05 100644 (file)
@@ -44,7 +44,8 @@ enum
   GTK_CLIST_SHOW_TITLES     = 1 << 4,
   GTK_CLIST_CONSTRUCTED            = 1 << 5,
   GTK_CLIST_CHILD_HAS_FOCUS = 1 << 6,
-  GTK_CLIST_ADD_MODE        = 1 << 7
+  GTK_CLIST_ADD_MODE        = 1 << 7,
+  GTK_CLIST_AUTO_SORT       = 1 << 8
 }; 
 
 /* cell types */
@@ -75,6 +76,7 @@ typedef enum
 #define GTK_CLIST_CHILD_HAS_FOCUS(clist)   (GTK_CLIST_FLAGS (clist) & GTK_CLIST_CHILD_HAS_FOCUS)
 #define GTK_CLIST_DRAG_SELECTION(clist)    (GTK_CLIST_FLAGS (clist) & GTK_CLIST_DRAG_SELECTION)
 #define GTK_CLIST_ADD_MODE(clist)          (GTK_CLIST_FLAGS (clist) & GTK_CLIST_ADD_MODE)
+#define GTK_CLIST_AUTO_SORT(clist)         (GTK_CLIST_FLAGS (clist) & GTK_CLIST_AUTO_SORT)
 
 #define GTK_CLIST_ROW(_glist_) ((GtkCListRow *)((_glist_)->data))
 
@@ -95,6 +97,10 @@ typedef struct _GtkCellPixmap GtkCellPixmap;
 typedef struct _GtkCellPixText GtkCellPixText;
 typedef struct _GtkCellWidget GtkCellWidget;
 
+typedef gint (*GtkCListCompareFunc) (GtkCList     *clist,
+                                    gconstpointer ptr1,
+                                    gconstpointer ptr2);
+
 struct _GtkCList
 {
   GtkContainer container;
@@ -176,56 +182,56 @@ struct _GtkCList
   gint drag_pos;
   gint htimer;
   gint vtimer;
+
+  GtkSortType sort_type;
+  GtkCListCompareFunc compare;
+  gint sort_column;
 };
 
 struct _GtkCListClass
 {
   GtkContainerClass parent_class;
   
-  void (*select_row) (GtkCList * clist,
-                     gint row,
-                     gint column,
-                     GdkEvent * event);
-  void (*unselect_row) (GtkCList * clist,
-                       gint row,
-                       gint column,
-                       GdkEvent * event);
-  void (*click_column) (GtkCList * clist,
-                       gint column);
-
-  void (*toggle_focus_row) (GtkCList * clist);
-  void (*select_all) (GtkCList * clist);
-  void (*unselect_all) (GtkCList * clist);
-  void (*undo_selection) (GtkCList * clist);
-  void (*start_selection) (GtkCList * clist);
-  void (*end_selection) (GtkCList * clist);
-  void (*extend_selection) (GtkCList * clist,
-                           GtkScrollType scroll_type,
-                           gfloat position,
-                           gboolean auto_start_selection);
-  void (*scroll_horizontal) (GtkCList * clist,
-                            GtkScrollType scroll_type,
-                            gfloat position);
-  void (*scroll_vertical) (GtkCList * clist,
-                          GtkScrollType scroll_type,
-                          gfloat position);
-  void (*toggle_add_mode) (GtkCList * clist);
+  void (*select_row)          (GtkCList * clist,
+                              gint row,
+                              gint column,
+                              GdkEvent * event);
+  void (*unselect_row)        (GtkCList * clist,
+                              gint row,
+                              gint column,
+                              GdkEvent * event);
+  void (*click_column)        (GtkCList * clist,
+                              gint column);
+  void (*toggle_focus_row)    (GtkCList * clist);
+  void (*select_all)          (GtkCList * clist);
+  void (*unselect_all)        (GtkCList * clist);
+  void (*undo_selection)      (GtkCList * clist);
+  void (*start_selection)     (GtkCList * clist);
+  void (*end_selection)        (GtkCList * clist);
+  void (*extend_selection)    (GtkCList * clist,
+                              GtkScrollType scroll_type,
+                              gfloat position,
+                              gboolean auto_start_selection);
+  void (*scroll_horizontal)   (GtkCList * clist,
+                              GtkScrollType scroll_type,
+                              gfloat position);
+  void (*scroll_vertical)     (GtkCList * clist,
+                              GtkScrollType scroll_type,
+                              gfloat position);
+  void (*toggle_add_mode)     (GtkCList * clist);
   void (*abort_column_resize) (GtkCList * clist);
-
-  void (*resync_selection) (GtkCList * clist,
-                           GdkEvent * event);
-  GList * (*selection_find) (GtkCList *clist,
-                            gint row_number,
-                            GList *row_list_element);
-  void (*draw_row) (GtkCList * clist,
-                   GdkRectangle * area,
-                   gint row,
-                   GtkCListRow * clist_row);
-  void (*clear) (GtkCList * clist);
-  void (*fake_unselect_all) (GtkCList * clist,
-                            gint row);
-        
-
+  void (*resync_selection)    (GtkCList * clist,
+                              GdkEvent * event);
+  GList * (*selection_find)   (GtkCList *clist,
+                              gint row_number,
+                              GList *row_list_element);
+  void (*draw_row)            (GtkCList * clist,
+                              GdkRectangle * area,
+                              gint row,
+                              GtkCListRow * clist_row);
+  void (*clear)               (GtkCList * clist);
+  void (*fake_unselect_all)   (GtkCList * clist,
+                              gint row);
 
   gint scrollbar_spacing;
 };
@@ -493,8 +499,9 @@ void gtk_clist_set_shift (GtkCList * clist,
 gint gtk_clist_append (GtkCList * clist,
                       gchar * text[]);
 
-/* inserts a row at index row */
-void gtk_clist_insert (GtkCList * clist,
+/* inserts a row at index row and returns the row where it was actually
+inserted (may be different from "row" in auto_sort mode) */
+gint gtk_clist_insert (GtkCList * clist,
                       gint row,
                       gchar * text[]);
 
@@ -555,9 +562,27 @@ void gtk_clist_unselect_all (GtkCList *clist);
 /* swap the position of two rows */
 void gtk_clist_swap_rows (GtkCList * clist, gint row1, gint row2);
 
+/* sets a compare function different to the default */
+void gtk_clist_set_compare_func (GtkCList            *clist,
+                                GtkCListCompareFunc  cmp_func);
+
+/* the column to sort by */
+void gtk_clist_set_sort_column (GtkCList *clist,
+                               gint      column);
+
+/* how to sort : ascending or descending */
+void gtk_clist_set_sort_type (GtkCList   *clist,
+                             GtkSortType sort_type);
+
+/* sort the list with the current compare function */
+void gtk_clist_sort (GtkCList *clist);
+
+/* Automatically sort upon insertion */
+void gtk_clist_set_auto_sort (GtkCList *clist,
+                             gboolean  auto_sort);
+
 #ifdef __cplusplus
 }
 #endif                         /* __cplusplus */
 
-
 #endif                         /* __GTK_CLIST_H__ */
index 1b4ea3eccd2439e6d71e1850d8c7b7dae31d3f59..e69dfac88a07f9f249ba7e609c681ed3641cae2e 100644 (file)
@@ -177,12 +177,9 @@ static gboolean ctree_is_hot_spot       (GtkCTree      *ctree,
 static void tree_sort                   (GtkCTree      *ctree,
                                         GtkCTreeNode  *node,
                                         gpointer       data);
-static gint default_compare             (GtkCTree           *ctree,
-                                        const GtkCTreeNode *node1,
-                                        const GtkCTreeNode *node2);
-
-
-
+static gint default_compare             (GtkCList     *clist,
+                                        gconstpointer ptr1,
+                                        gconstpointer ptr2);
 static void fake_unselect_all           (GtkCList      *clist,
                                         gint           row);
 static GList * selection_find           (GtkCList      *clist,
@@ -406,8 +403,7 @@ gtk_ctree_init (GtkCTree *ctree)
   ctree->drag_source    = NULL;
   ctree->drag_target    = NULL;
   ctree->insert_pos     = GTK_CTREE_POS_AS_CHILD;
-  ctree->node_compare   = default_compare;
-  ctree->auto_sort      = FALSE;
+  GTK_CLIST (ctree)->compare = default_compare;
   ctree->reorderable    = FALSE;
   ctree->use_icons      = TRUE;
   ctree->in_drag        = FALSE;
@@ -2741,7 +2737,7 @@ real_tree_move (GtkCTree     *ctree,
       clist->undo_unselection = NULL;
     }
 
-  if (ctree->auto_sort)
+  if (GTK_CLIST_AUTO_SORT (clist))
     {
       if (new_parent == GTK_CTREE_ROW (node)->parent)
        return;
@@ -2751,7 +2747,7 @@ real_tree_move (GtkCTree     *ctree,
       else
        new_sibling = GTK_CTREE_NODE (clist->row_list);
 
-      while (new_sibling && ctree->node_compare (ctree, node, new_sibling) > 0)
+      while (new_sibling && clist->compare (clist, node, new_sibling) > 0)
        new_sibling = GTK_CTREE_ROW (new_sibling)->sibling;
     }
 
@@ -3624,21 +3620,23 @@ ctree_is_hot_spot (GtkCTree     *ctree,
 }
 
 static gint
-default_compare (GtkCTree    *ctree,
-                const GtkCTreeNode *node1,
-                const GtkCTreeNode *node2)
+default_compare (GtkCList     *clist,
+                gconstpointer ptr1,
+                gconstpointer ptr2)
 {
+  GtkCTreeNode *node1 = (GtkCTreeNode *) ptr1;
+  GtkCTreeNode *node2 = (GtkCTreeNode *) ptr2;
   char *text1;
   char *text2;
 
   text1 = GTK_CELL_PIXTEXT (GTK_CTREE_ROW
-                           (node1)->row.cell[ctree->tree_column])->text;
+                           (node1)->row.cell[clist->sort_column])->text;
   text2 = GTK_CELL_PIXTEXT (GTK_CTREE_ROW
-                           (node2)->row.cell[ctree->tree_column])->text;
+                           (node2)->row.cell[clist->sort_column])->text;
+
   return strcmp (text1, text2);
 }
 
-
 /***********************************************************
  ***********************************************************
  ***                  Public interface                   ***
@@ -3744,14 +3742,14 @@ gtk_ctree_insert (GtkCTree     *ctree,
                 mask_closed, pixmap_opened, mask_opened, is_leaf, expanded);
 
   /* sorted insertion */
-  if (ctree->auto_sort)
+  if (GTK_CLIST_AUTO_SORT (clist))
     {
       if (parent)
        sibling = GTK_CTREE_ROW (parent)->children;
       else
        sibling = GTK_CTREE_NODE (clist->row_list);
 
-      while (sibling && ctree->node_compare (ctree, node, sibling) > 0)
+      while (sibling && clist->compare (clist, node, sibling) > 0)
        sibling = GTK_CTREE_ROW (sibling)->sibling;
     }
 
@@ -3771,6 +3769,7 @@ gtk_ctree_insert_gnode (GtkCTree          *ctree,
                        GtkCTreeGNodeFunc  func,
                        gpointer           data)
 {
+  GtkCList *clist;
   GtkCTreeNode *cnode = NULL;
   GtkCTreeNode *child = NULL;
   GtkCTreeNode *new_child;
@@ -3785,6 +3784,8 @@ gtk_ctree_insert_gnode (GtkCTree          *ctree,
   if (sibling)
     g_return_val_if_fail (GTK_CTREE_ROW (sibling)->parent == parent, NULL);
   
+  clist = GTK_CLIST (ctree);
+
   if (parent)
     depth = GTK_CTREE_ROW (parent)->level + 1;
 
@@ -3802,17 +3803,17 @@ gtk_ctree_insert_gnode (GtkCTree          *ctree,
       return NULL;
     }
 
-  if ((thaw = !GTK_CLIST_FROZEN (GTK_CLIST (ctree))))
-    gtk_clist_freeze (GTK_CLIST (ctree));
+  if ((thaw = !GTK_CLIST_FROZEN (clist)))
+    gtk_clist_freeze (clist);
 
-  if (ctree->auto_sort)
+  if (GTK_CLIST_AUTO_SORT (clist))
     {
       if (parent)
        sibling = GTK_CTREE_ROW (parent)->children;
       else
-       sibling = GTK_CTREE_NODE (GTK_CLIST (ctree)->row_list);
+       sibling = GTK_CTREE_NODE (clist->row_list);
 
-      while (sibling && ctree->node_compare (ctree, cnode, sibling) > 0)
+      while (sibling && clist->compare (clist, cnode, sibling) > 0)
        sibling = GTK_CTREE_ROW (sibling)->sibling;
     }
 
@@ -3827,7 +3828,7 @@ gtk_ctree_insert_gnode (GtkCTree          *ctree,
     }  
   
   if (thaw) 
-    gtk_clist_thaw (GTK_CLIST (ctree));
+    gtk_clist_thaw (clist);
 
   return cnode;
 }
@@ -4981,65 +4982,47 @@ gtk_ctree_set_line_style (GtkCTree          *ctree,
  ***********************************************************/
 
 
-void       
-gtk_ctree_set_auto_sort (GtkCTree *ctree,
-                        gboolean  auto_sort)
-{
-  g_return_if_fail (ctree != NULL);
-  g_return_if_fail (GTK_IS_CTREE (ctree));
-  
-  if (ctree->auto_sort == (auto_sort != 0))
-    return;
-
-  ctree->auto_sort = (auto_sort != 0);
-
-  if (auto_sort)
-    gtk_ctree_sort_recursive (ctree, NULL);
-}
-
-void
-gtk_ctree_set_compare_func (GtkCTree            *ctree,
-                           GtkCTreeCompareFunc  cmp_func)
-{
-  g_return_if_fail (ctree != NULL);
-  g_return_if_fail (GTK_IS_CTREE (ctree));
-
-  if (cmp_func == NULL)
-    ctree->node_compare = default_compare;
-  else
-    ctree->node_compare = cmp_func;
-}
-
 static void
 tree_sort (GtkCTree     *ctree,
           GtkCTreeNode *node,
           gpointer      data)
 {
   GtkCTreeNode *list_start;
-  GtkCTreeNode *max;
+  GtkCTreeNode *cmp;
   GtkCTreeNode *work;
+  GtkCList *clist;
+
+  clist = GTK_CLIST (ctree);
 
   if (node)
     list_start = GTK_CTREE_ROW (node)->children;
   else
-    list_start = GTK_CTREE_NODE (GTK_CLIST (ctree)->row_list);
+    list_start = GTK_CTREE_NODE (clist->row_list);
 
   while (list_start)
     {
-      max = list_start;
-      work = GTK_CTREE_ROW (max)->sibling;
+      cmp = list_start;
+      work = GTK_CTREE_ROW (cmp)->sibling;
       while (work)
        {
-         if (ctree->node_compare (ctree, work, max) < 0)
-           max = work;
+         if (clist->sort_type == GTK_SORT_ASCENDING)
+           {
+             if (clist->compare (clist, work, cmp) < 0)
+               cmp = work;
+           }
+         else
+           {
+             if (clist->compare (clist, work, cmp) > 0)
+               cmp = work;
+           }
          work = GTK_CTREE_ROW (work)->sibling;
        }
-      if (max == list_start)
-       list_start = GTK_CTREE_ROW (max)->sibling;
+      if (cmp == list_start)
+       list_start = GTK_CTREE_ROW (cmp)->sibling;
       else
        {
-         gtk_ctree_unlink (ctree, max, FALSE);
-         gtk_ctree_link (ctree, max, node, list_start, FALSE);
+         gtk_ctree_unlink (ctree, cmp, FALSE);
+         gtk_ctree_link (ctree, cmp, node, list_start, FALSE);
        }
     }
 }
index 77f5fb7bd5a0b90e43e66c672cba10379323d109..c9d9b5e1bd844f0320366d8b5025f5bcadb10949 100644 (file)
@@ -81,17 +81,12 @@ typedef void (*GtkCTreeFunc) (GtkCTree     *ctree,
                              GtkCTreeNode *node,
                              gpointer      data);
 
-typedef gint (*GtkCTreeCompareFunc) (GtkCTree    *ctree,
-                                    const GtkCTreeNode *node1,
-                                    const GtkCTreeNode *node2);
-
 typedef gboolean (*GtkCTreeGNodeFunc) (GtkCTree     *ctree,
                                        guint         depth,
                                        GNode        *gnode,
                                       GtkCTreeNode *cnode,
                                        gpointer      data);
 
-
 struct _GtkCTree
 {
   GtkCList clist;
@@ -108,9 +103,7 @@ struct _GtkCTree
   GtkCTreeNode *drag_source;
   GtkCTreeNode *drag_target;
   gint insert_pos;
-  GtkCTreeCompareFunc node_compare;
-  
-  guint auto_sort   : 1;
+
   guint reorderable : 1;
   guint use_icons   : 1;
   guint in_drag     : 1;
@@ -384,10 +377,6 @@ void       gtk_ctree_set_line_style         (GtkCTree     *ctree,
  *             Tree sorting functions                      *
  ***********************************************************/
 
-void       gtk_ctree_set_auto_sort          (GtkCTree     *ctree,
-                                            gboolean      auto_sort);
-void       gtk_ctree_set_compare_func       (GtkCTree     *ctree,
-                                            GtkCTreeCompareFunc cmp_func);
 void       gtk_ctree_sort                   (GtkCTree     *ctree, 
                                             GtkCTreeNode *node);
 void       gtk_ctree_sort_recursive         (GtkCTree     *ctree, 
index ecfe5ca95a0ac2f436bcbb3607a46628f700f5fa..86504ea756dbc3124b828e40192deee116efa467 100644 (file)
@@ -305,6 +305,13 @@ typedef enum
   GTK_WINDOW_POPUP
 } GtkWindowType;
 
+/* How to sort */
+typedef enum
+{
+  GTK_SORT_ASCENDING,
+  GTK_SORT_DESCENDING
+} GtkSortType;
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index 28aac144cb32e689f5e6c1c36357561008245346..6658a342ed2cef959ad2cbb97c81f653adc47bfe 100644 (file)
@@ -3150,10 +3150,11 @@ add1000_clist (GtkWidget *widget, gpointer data)
   gtk_clist_freeze (GTK_CLIST (data));
   for (i = 0; i < 1000; i++)
     {
-      sprintf (text[0], "Row %d", clist_rows++);
+      sprintf (text[0], "Row %d", rand() % 10000 /*clist_rows++*/);
       row = gtk_clist_append (GTK_CLIST (data), texts);
       gtk_clist_set_pixtext (GTK_CLIST (data), row, 3, "Hello World", 5, pixmap, mask);
     }
+
   gtk_clist_thaw (GTK_CLIST (data));
 
   gdk_pixmap_unref (pixmap);
@@ -3179,7 +3180,7 @@ add10000_clist (GtkWidget *widget, gpointer data)
   gtk_clist_freeze (GTK_CLIST (data));
   for (i = 0; i < 10000; i++)
     {
-      sprintf (text[0], "Row %d", clist_rows++);
+      sprintf (text[0], "Row %d", rand() % 10000 /*clist_rows++*/);
       gtk_clist_append (GTK_CLIST (data), texts);
     }
   gtk_clist_thaw (GTK_CLIST (data));
@@ -3342,7 +3343,10 @@ insert_row_clist (GtkWidget *widget, gpointer data)
     "This", "is", "a", "inserted", "row."
   };
 
-  gtk_clist_insert (GTK_CLIST (data), GTK_CLIST (data)->focus_row, text);
+  if (GTK_CLIST (data)->focus_row >= 0)
+    gtk_clist_insert (GTK_CLIST (data), GTK_CLIST (data)->focus_row, text);
+  else
+    gtk_clist_insert (GTK_CLIST (data), 0, text);
 
   clist_rows++;
 }
@@ -3393,6 +3397,22 @@ clist_toggle_sel_mode (GtkWidget *widget, GtkCList *clist)
   gtk_clist_set_selection_mode (clist, (GtkSelectionMode) (3-i));
 }
 
+static void 
+clist_click_column (GtkCList *clist, gint column, gpointer data)
+{
+  if (column == clist->sort_column)
+    {
+      if (clist->sort_type == GTK_SORT_ASCENDING)
+       clist->sort_type = GTK_SORT_DESCENDING;
+      else
+       clist->sort_type = GTK_SORT_ASCENDING;
+    }
+  else
+    gtk_clist_set_sort_column (clist, column);
+
+  gtk_clist_sort (clist);
+}
+
 static void
 create_clist (void)
 {
@@ -3451,6 +3471,10 @@ create_clist (void)
       clist = gtk_clist_new_with_titles (TESTGTK_CLIST_COLUMNS, titles);
       /*clist = gtk_clist_new (TESTGTK_CLIST_COLUMNS);*/
 
+      gtk_signal_connect (GTK_OBJECT (clist), "click_column",
+                         (GtkSignalFunc) clist_click_column,
+                         NULL);
+
       /* control buttons */
       button = gtk_button_new_with_label ("Add 1,000 Rows With Pixmaps");
       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
@@ -4032,6 +4056,26 @@ void rebuild_tree (GtkWidget *widget, GtkCTree *ctree)
   after_press (ctree, NULL);
 }
 
+static void 
+ctree_click_column (GtkCTree *ctree, gint column, gpointer data)
+{
+  GtkCList *clist;
+
+  clist = GTK_CLIST (ctree);
+
+  if (column == clist->sort_column)
+    {
+      if (clist->sort_type == GTK_SORT_ASCENDING)
+       clist->sort_type = GTK_SORT_DESCENDING;
+      else
+       clist->sort_type = GTK_SORT_ASCENDING;
+    }
+  else
+    gtk_clist_set_sort_column (clist, column);
+
+  gtk_ctree_sort_recursive (ctree, NULL);
+}
+
 void create_ctree (void)
 {
   static GtkWidget *window = NULL;
@@ -4132,6 +4176,9 @@ void create_ctree (void)
       ctree = GTK_CTREE (gtk_ctree_new_with_titles (2, 0, title));
       gtk_ctree_set_line_style (ctree, GTK_CTREE_LINES_DOTTED);
       gtk_ctree_set_reorderable (ctree, TRUE);
+      gtk_signal_connect (GTK_OBJECT (ctree), "click_column",
+                         (GtkSignalFunc) ctree_click_column,
+                         NULL);
       gtk_signal_connect (GTK_OBJECT (ctree), "button_press_event",
                          GTK_SIGNAL_FUNC (button_press), NULL);
       gtk_signal_connect_after (GTK_OBJECT (ctree), "button_press_event",
@@ -4154,7 +4201,6 @@ void create_ctree (void)
                                GTK_SIGNAL_FUNC (after_press), NULL);
       
       gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (ctree), TRUE, TRUE, 0);
-      gtk_clist_column_titles_passive (GTK_CLIST (ctree));
       gtk_clist_set_selection_mode (GTK_CLIST (ctree), GTK_SELECTION_EXTENDED);
       gtk_clist_set_policy (GTK_CLIST (ctree), GTK_POLICY_ALWAYS, 
                            GTK_POLICY_AUTOMATIC);
index 28aac144cb32e689f5e6c1c36357561008245346..6658a342ed2cef959ad2cbb97c81f653adc47bfe 100644 (file)
@@ -3150,10 +3150,11 @@ add1000_clist (GtkWidget *widget, gpointer data)
   gtk_clist_freeze (GTK_CLIST (data));
   for (i = 0; i < 1000; i++)
     {
-      sprintf (text[0], "Row %d", clist_rows++);
+      sprintf (text[0], "Row %d", rand() % 10000 /*clist_rows++*/);
       row = gtk_clist_append (GTK_CLIST (data), texts);
       gtk_clist_set_pixtext (GTK_CLIST (data), row, 3, "Hello World", 5, pixmap, mask);
     }
+
   gtk_clist_thaw (GTK_CLIST (data));
 
   gdk_pixmap_unref (pixmap);
@@ -3179,7 +3180,7 @@ add10000_clist (GtkWidget *widget, gpointer data)
   gtk_clist_freeze (GTK_CLIST (data));
   for (i = 0; i < 10000; i++)
     {
-      sprintf (text[0], "Row %d", clist_rows++);
+      sprintf (text[0], "Row %d", rand() % 10000 /*clist_rows++*/);
       gtk_clist_append (GTK_CLIST (data), texts);
     }
   gtk_clist_thaw (GTK_CLIST (data));
@@ -3342,7 +3343,10 @@ insert_row_clist (GtkWidget *widget, gpointer data)
     "This", "is", "a", "inserted", "row."
   };
 
-  gtk_clist_insert (GTK_CLIST (data), GTK_CLIST (data)->focus_row, text);
+  if (GTK_CLIST (data)->focus_row >= 0)
+    gtk_clist_insert (GTK_CLIST (data), GTK_CLIST (data)->focus_row, text);
+  else
+    gtk_clist_insert (GTK_CLIST (data), 0, text);
 
   clist_rows++;
 }
@@ -3393,6 +3397,22 @@ clist_toggle_sel_mode (GtkWidget *widget, GtkCList *clist)
   gtk_clist_set_selection_mode (clist, (GtkSelectionMode) (3-i));
 }
 
+static void 
+clist_click_column (GtkCList *clist, gint column, gpointer data)
+{
+  if (column == clist->sort_column)
+    {
+      if (clist->sort_type == GTK_SORT_ASCENDING)
+       clist->sort_type = GTK_SORT_DESCENDING;
+      else
+       clist->sort_type = GTK_SORT_ASCENDING;
+    }
+  else
+    gtk_clist_set_sort_column (clist, column);
+
+  gtk_clist_sort (clist);
+}
+
 static void
 create_clist (void)
 {
@@ -3451,6 +3471,10 @@ create_clist (void)
       clist = gtk_clist_new_with_titles (TESTGTK_CLIST_COLUMNS, titles);
       /*clist = gtk_clist_new (TESTGTK_CLIST_COLUMNS);*/
 
+      gtk_signal_connect (GTK_OBJECT (clist), "click_column",
+                         (GtkSignalFunc) clist_click_column,
+                         NULL);
+
       /* control buttons */
       button = gtk_button_new_with_label ("Add 1,000 Rows With Pixmaps");
       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
@@ -4032,6 +4056,26 @@ void rebuild_tree (GtkWidget *widget, GtkCTree *ctree)
   after_press (ctree, NULL);
 }
 
+static void 
+ctree_click_column (GtkCTree *ctree, gint column, gpointer data)
+{
+  GtkCList *clist;
+
+  clist = GTK_CLIST (ctree);
+
+  if (column == clist->sort_column)
+    {
+      if (clist->sort_type == GTK_SORT_ASCENDING)
+       clist->sort_type = GTK_SORT_DESCENDING;
+      else
+       clist->sort_type = GTK_SORT_ASCENDING;
+    }
+  else
+    gtk_clist_set_sort_column (clist, column);
+
+  gtk_ctree_sort_recursive (ctree, NULL);
+}
+
 void create_ctree (void)
 {
   static GtkWidget *window = NULL;
@@ -4132,6 +4176,9 @@ void create_ctree (void)
       ctree = GTK_CTREE (gtk_ctree_new_with_titles (2, 0, title));
       gtk_ctree_set_line_style (ctree, GTK_CTREE_LINES_DOTTED);
       gtk_ctree_set_reorderable (ctree, TRUE);
+      gtk_signal_connect (GTK_OBJECT (ctree), "click_column",
+                         (GtkSignalFunc) ctree_click_column,
+                         NULL);
       gtk_signal_connect (GTK_OBJECT (ctree), "button_press_event",
                          GTK_SIGNAL_FUNC (button_press), NULL);
       gtk_signal_connect_after (GTK_OBJECT (ctree), "button_press_event",
@@ -4154,7 +4201,6 @@ void create_ctree (void)
                                GTK_SIGNAL_FUNC (after_press), NULL);
       
       gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (ctree), TRUE, TRUE, 0);
-      gtk_clist_column_titles_passive (GTK_CLIST (ctree));
       gtk_clist_set_selection_mode (GTK_CLIST (ctree), GTK_SELECTION_EXTENDED);
       gtk_clist_set_policy (GTK_CLIST (ctree), GTK_POLICY_ALWAYS, 
                            GTK_POLICY_AUTOMATIC);